﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;

namespace SCG.WinForms
{
    public static class ImageUtils
    {
        //convert a bitmap to a string
        public static string ImageToString(Image img)
        {
            string s = "";
            using (MemoryStream ms = new MemoryStream())
            {
                Image newImage = ImageUtils.ResizeBitmap(img, img.Width, img.Height, false);
                newImage.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
                byte[] bytes = ms.GetBuffer();
                s = Convert.ToBase64String(bytes);
            }
            return s;
        }

        //convert a string to a bitmap
        public static Image StringToImage(string s)
        {
            byte[] bytes = Convert.FromBase64String(s);
            using (MemoryStream ms = new MemoryStream(bytes))
            {
                return Image.FromStream(ms);
            }
        }

        //resize a bitmap with or without scaling
        public static Bitmap ResizeBitmap(Image img, int width, int height, bool stretch)
        {
            Bitmap bmp = new Bitmap(width, height, PixelFormat.Format32bppPArgb);
            Graphics gr = Graphics.FromImage(bmp);
            using (gr)
            {
                if (stretch)
                {
                    gr.DrawImage(img, new Rectangle(0, 0, width, height));
                }
                else
                {
                    int x = (width - img.Width) / 2;
                    int y = (height - img.Height) / 2;
                    gr.DrawImageUnscaled(img, new Point(x, y));
                }
            }
            return bmp;
        }

        //create bitmap format for most efficient rendering in TurboSprite
        public static Bitmap Create32bppBitmap(Bitmap bmp)
        {
            if (bmp.PixelFormat == PixelFormat.Format32bppPArgb)
                return bmp;
            Bitmap bmpNew = new Bitmap(bmp.Width, bmp.Height, PixelFormat.Format32bppPArgb);
            Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
            Graphics gr = Graphics.FromImage(bmpNew);
            using (gr)
            {
                gr.DrawImage(bmp, rect, rect, GraphicsUnit.Pixel);
            }
            return bmpNew;
        }

        //colorize a bitmap
        public static Bitmap ColorizeBitmap(Bitmap bmp, Color color, Color transparent)
        {
            Color c;
            float red = color.R;
            float green = color.G;
            float blue = color.B;
            byte newRed, newGreen, newBlue;
            float pct;
            Bitmap colorized = new Bitmap(bmp.Width, bmp.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            Graphics g = Graphics.FromImage(colorized);
            using (g)
            {
                g.DrawImage(bmp, new Rectangle(0, 0, bmp.Width, bmp.Height));
            }
            for (int x = 0; x < colorized.Width; x++)
                for (int y = 0; y < colorized.Height; y++)
                {
                    c = colorized.GetPixel(x, y);
                    pct = (float)c.R / 255f;
                    newRed = (byte)(red * pct);
                    pct = (float)c.G / 255f;
                    newGreen = (byte)(green * pct);
                    pct = (float)c.B / 255f;
                    newBlue = (byte)(blue * pct);
                    colorized.SetPixel(x, y, Color.FromArgb(c.A, newRed, newGreen, newBlue));
                }
            if (transparent != Color.Transparent)
                colorized.MakeTransparent(transparent);
            return colorized;
        }

        //apply an alpha to a bitmap
        public static Bitmap BitmapWithAlpha(Bitmap bmp, float alpha)
        {
            if (alpha >= 1)
                return bmp;
            Bitmap a = new Bitmap(bmp.Width, bmp.Height, System.Drawing.Imaging.PixelFormat.Format32bppPArgb);
            Graphics g = Graphics.FromImage(a);
            using (g)
            {
                ColorMatrix colorMatrix = new ColorMatrix
                (
                    new float[][] 
                        {
                            new float[] {1, 0, 0, 0, 0}, 
                            new float[] {0, 1, 0, 0, 0},
                            new float[] {0, 0, 1, 0, 0},
                            new float[] {0, 0, 0, alpha, 0},
                            new float[] {0, 0, 0, 0, 1}
                        }
                );
                ImageAttributes ia = new ImageAttributes();
                using (ia)
                {
                    ia.SetColorMatrix(colorMatrix);
                    Rectangle rc = new Rectangle(0, 0, bmp.Width, bmp.Height);
                    g.DrawImage(bmp, rc, 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, ia);
                }
            }
            return a;
        }

        //rotate a bitmap
        public static Image RotateImage(Image img, float rotationAngle)
        {
            Bitmap bmp = new Bitmap(img.Width, img.Height);
            Graphics g = Graphics.FromImage(bmp);
            using (g)
            {
                g.TranslateTransform((float)bmp.Width / 2, (float)bmp.Height / 2);
                g.RotateTransform(rotationAngle);
                g.TranslateTransform(-(float)bmp.Width / 2, -(float)bmp.Height / 2);
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                g.DrawImage(img, new Point(0, 0));
            }

            //return the image
            return bmp;
        }
    }
}
